--
-- @Author:      
-- @DateTime:    2019-04-19 14:02:03
-- @Description: 用户对象,座位管理
--  

local error_code = require("error_code")
local UserInfo = import("UserInfo")

local table_insert = table.insert
local table_remove = table.remove
local table_mix = table.mix

local UserManager = class("UserManager")

-- 初始化
function UserManager:ctor(room_config)
    self.room_config = room_config --房间配置
    self.user_list = {} --玩家列表
    self.seat_list = {} --座位列表
    self.curr_locked_uids = {} --uid锁定列表
    self.rich_seat_id = 1 --最有钱的座位
    self.luch_seat_id = 4 --神算子座位

end

function UserManager:start()
    self.bairen_desk = global.bairen_desk
    self.banker_manager = global.banker_manager
end

-- 重置数据
function UserManager:clear()
    for uid, v in pairs(self.user_list) do 
        self:removeUser(uid)
    end
    self.user_list = {} --玩家列表
    self.seat_list = {} --座位列表
end

-- 获取用户列表
function UserManager:getUserList()
	return self.user_list
end

--取玩家信息
function UserManager:getUserInfo(user_id)
	return self.user_list[user_id]
end
function UserManager:getUser(user_id)
    local user = self.user_list[user_id]
    if not user then
        -- errlog("not find user  uid:",user_id)
        -- assert(false, "____________getUser")
        return nil
    end
    return user
end

-- 查找用户信息
function UserManager:searchUserInfo(user_id)
    return self.user_list[user_id]
end

-- 创建用户信息
function UserManager:createUserInfo(uid)
     --先拉取玩家信息
    local ok,base_data = R().basesvr{key=uid}:call('.msg_handler','get_base_data',uid)
    if not ok then
        errlog(uid,'failed to get base_data',uid)
        return false
    end
    -- dbglog("____玩家进桌base_data_____", tostring_r(base_data))
    --再拉取玩家的登入信息 跟大厅拉取
    local ok,enter_data = R().hallsvr{key=uid}:call('.msg_handler','get_enter_data',uid)
    if not ok then
        errlog(uid,'failed to get enter_data')
        enter_data = {}
    end
    dbglog("____玩家进桌enter_data_____", enter_data)
    local user_info = UserInfo.new(base_data, enter_data)

    return user_info
end

--添加用户信息
function UserManager:addUserInfo(uid)	
    --玩家已存在
    local user = self.user_list[uid]
    if user then    
        return true
    end  
    --拉取玩家信息
    local user_info = self:createUserInfo(uid)
    if not user_info then
        return false, 1 --创建失败
    end

    if not self:lockOnePlayer(uid) then
        errlog(uid,'____failed to lockOnePlayer')
        return false, 2 --已锁住
    end
    if self:getUserNum() >= self.room_config:getMaxUserNum() then
        self:unlockOnePlayer(uid)
        return false, 3 --人数超过限制
    end
    dbglog("addUserInfo:",uid)
    self.user_list[uid] = user_info
	return true
end

--添加用户信息
function UserManager:addRobot(base_data, enter_data)   
    --玩家已存在
    local uid = base_data.uid
    local user = self.user_list[uid]
    if user then    
        return true
    end  
    local user = UserInfo.new(base_data, enter_data)
    if not user then
        return false, 1 --创建失败
    end
    if self:getUserNum() >= self.room_config:getMaxUserNum() then
        return false, 3 --人数超过限制
    end
    user:setFD(-1)
    user:setIsRobot(true) --是机器人
    -- dbglog("_____________2___addRobot_________")
    self.user_list[uid] = user
    return true
end

--更新用户信息
function UserManager:updateUserInfo(user_info)
    local user_id = user_info.user_id
    if self.user_list[user_id] then

        local function _update(des, src)
            for k, v in pairs(src) do
                if type(v) == 'table' then
                    if not des[k] then des[k] = {} end
                    _update(des[k], v)
                else
                    des[k] = v
                end
            end
        end
        _update(self.user_list[user_id], user_info)
    end
end

--重新加载玩家信息
function UserManager:setUserInfo(user_info)	
	if not self.user_list[user_info.user_id] then
		dbglog("_______setUserInfo_____")
		return false
    end     	
	self.user_list[user_info.user_id] = user_info
	return true
end

--移除用户信息
function UserManager:removeUser(uid)
	local user = self.user_list[uid]
    if not user then
		dbglog("_______removeUser_的玩家信息不存在____",user)
		return false
    end 	
    local seat_id = user:getSeatId()
    self:standUp(uid)
    self:unlockOnePlayer(uid) --解锁玩家
    self.user_list[uid] = nil

    --补上富豪位
    if self.bairen_desk and (seat_id == 1 or seat_id == 4) then 
        self.bairen_desk:specialRobotSitdown()
    end

    dbglog("__UserManager_user_id_删除_", uid )
	return true
end


--设置所有玩家的状态值
function UserManager:setAllUserValue(name, value)
    for user_id, user in pairs(self.user_list) do 
        user[name] = value
    end
end

function UserManager:setUserValue(user_id, name, value)
    local user = self.user_list[user_id]
    if user then 
        user[name] = value        
    end
end

function UserManager:getPlayingUser()
    local users = {}
    for user_id, user in pairs(self.user_list) do 
        if user.playing then 
            users[user_id] = user
        end
    end
    return users
end

--取有座位的玩家列表
function UserManager:getSeatUsers()
    local users = {}
    for seat_id, uid in pairs(self.seat_list) do 
        table_insert(users, self:getUser(uid))
    end
    return users
end

--取有座位的玩家
function UserManager:getSeatUser(seat_id)
    local user_id = self.seat_list[seat_id]
    if not user_id then 
        return nil
    end
    return self:getUser(user_id)
end

--取无座位的玩家
function UserManager:getNoSeatUsers()
    local users = {}
    for user_id, user in pairs(self.user_list) do 
        local seat_id = user:getSeatId()
        if not seat_id or seat_id<=0 then 
            users[user_id] = user
        end
    end
    return users
end

--取人数
function UserManager:getUserNum()
    local num = 0
    for _, user in pairs(self.user_list) do 
        if user then 
            num = num + 1
        end
    end
    return num
end

--取有座位的玩家数
function UserManager:getSeatUserNum()
    local nums = 0
    for seat_id, uid in pairs(self.seat_list) do 
        nums = nums + 1
    end
    return nums
end

--坐下
function UserManager:sitDown(uid, seat_id)

    local user = self.user_list[uid]
    if not user then 
        return false, error_code.RSP_FAIL
    end

    if seat_id == 1 or seat_id == 4 then 
        --富豪与神算子特殊
    else
        --金币是否够可以坐下
        local sitdown_coin = self.room_config:getSitdownCoin()
        if user:getCoins() < sitdown_coin then --小于最小可坐下需要的金币
            print("_____金币不够坐下", uid, user:getCoins(), sitdown_coin)
            return false, error_code.CANT_SITDOWN_NO_MONEY, sitdown_coin
        end

    end

    --找座位
    local seats = {}
    if seat_id and seat_id>0 then --指定座位        
        local user_id = self.seat_list[seat_id] 
        if not user_id or user_id==0 then 
            table_insert(seats, seat_id)
        else
            -- print("---------座位上已经有人---------------",user_id, seat_id, self.seat_list)
            return false, error_code.SEAT_IS_EMPLOY
        end
    else
        --找到空座位
        for id=1, 6 do --一般桌子都是6个座位
            local user_id = self.seat_list[id]
            if not user_id then 
                table_insert(seats, id)
            end
        end
        if #seats > 1 then 
            table_mix(seats) --随机位置    
        end        
    end
    if #seats > 0 then 
        seat_id = seats[1]
    else
        print("---------没有座位了-------")
        return false, error_code.CANT_SITDOWN
    end
    if user:isSeated() then --玩家已经坐下了，要换位置
        print("---------玩家已经坐下了-------", seat_id, user:getSeatId())
        return false, error_code.SEAT_FAIL_HAVE_SEAT
    end        
    self.seat_list[seat_id] = uid
    user:setSeatId(seat_id)
    return true, seat_id
end

--离座
function UserManager:standUp(user_id)
    if not user_id or user_id <=0 then
        return false
    end 
    local user = self.user_list[user_id]
    if not user then
        return false
    end
    local seatid = user:getSeatId()
    if seatid and seatid>0 then 
        self.seat_list[seatid] = nil        
    end
    user:setSeatId(0)
    return true
end





---------------------------------------------------------------------------



---------------------------------------------------------------------------
--玩家与房间锁定
function UserManager:lockOnePlayer(uid)
    local table_gid = self.room_config:getTableGid()
    local ok,succ = R().exdbsvr(1):call('.tlock_mgr','set_on_table',uid, table_gid, table_gid)
    if not ok then
        errlog(uid,'failed to set_on_table')
        return
    end
    if not succ then
        return
    end
    self.curr_locked_uids[uid] = true
    return true
end

--玩家与房间解锁
function UserManager:unlockOnePlayer(uid)
    local table_gid = self.room_config:getTableGid()
    R().exdbsvr(1):send('.tlock_mgr','unset_on_table', uid, table_gid)
    self.curr_locked_uids[uid] = nil
end

--取剩余可进游戏人数
function UserManager:getLeftUserNum()
    return self.room_config:getMaxUserNum() - self:getUserNum()
end

--取游戏人数(非机器人)
function UserManager:getRealUserNum()
    local num = 0
    for _, user in pairs(self.user_list) do         
        if not user:isRobot() then 
            num = num + 1
        end
    end
    return num    
end

--取下过注的人(非机器人)
function UserManager:getRealBetUsers()
    local users = {}
    for uid, user in pairs(self.user_list) do     
        if not user:isRobot() and user:getBeted() then 
            table_insert(users, user)
        end
    end    
    return users
end

-- --设置所有玩家的状态
-- function UserManager:setAllUserPlaying(playing)    
--     for _, user in pairs(self.user_list) do         
--         user:setPlaying(playing)
--     end    
-- end

--取机器人列表
--robot_type_id 类型id
function UserManager:getRobotList(robot_type_id)    
    local users = {}
    for _, user in pairs(self.user_list) do         
        if user:isRobot() then             
            if not robot_type_id or robot_type_id==user:getRobotTypeId() then                 
                table_insert(users, user)                
            end
        end
    end
    return users    
end

--桌子是否有机器人
function UserManager:haveRobot()    
    for _, user in pairs(self.user_list) do         
        if user:isRobot() then             
            return true
        end
    end
    if self.banker_manager then 
        local banker = self.banker_manager:getBanker()
        if banker:isRobot() then 
            return true
        end
    end
    return false    
end


return UserManager

